from __future__ import absolute_import
import logging
from forest.api import Command, get_tool
from forest.tools.system.mount import mount, bindmount, umount
from os.path import join
from time import sleep
logger = logging.getLogger('forest.files.execute')

class Execute(object):

    def run_check_modified(self, config, name):
        #for cmd_lines in config.get_resources().iter_all():
        #    print 'on', cmd_lines.get_id(), 'with ', cmd_lines.__register__

        for cmd_lines in config.get_resources().iter_by_type(name):
            logger.info('in execute {}'.format(cmd_lines.get_name()))
            depends = cmd_lines.get_depends()

            if not depends and not config.is_install():
                return

            if config.is_install():
                logger.info('executing - is install')
                self.exec_run(config, cmd_lines)
                continue

            for dependant in depends:
                if dependant in config.get_modified():
                    logger.info('executing - dependant {} modified'.format(dependant))
                    self.exec_run(config, cmd_lines)
                    break

    def exec_run(self, config, cmd_lines):
        def keep_test(line):
            return line.strip() != '' and not line.strip().startswith('#')

        clean_lines = cmd_lines.get_script().split('\n')
        # filter out empty or comments, after stripping them
        joining_lines = filter(keep_test, clean_lines)
        cmd_string = ' ; '.join(joining_lines)

        Command.SIGNAL_COMMAND_PROGRESS(self, message='Executing block: {}'.format(cmd_lines.get_name()))

        install_tree = config.get_install_root()
        if install_tree != '/':
            bindmount('/dev', join(install_tree, 'dev'))
            mount('none', join(install_tree, 'proc'), 'proc')
            mount('none', join(install_tree, 'sys'), 'sysfs')
        with get_tool('system.chroot')(install_tree):

            logger.info('executing the command {}'.format(cmd_string))
            for stat, line in get_tool('system.poll')(['sh', '-c', cmd_string]):
                print line
        if install_tree != '/':
            umount(join(install_tree, 'dev'), lazy=True)
            umount(join(install_tree, 'proc'), lazy=True)
            umount(join(install_tree, 'sys'), lazy=True)


class PreExecute(Command, Execute):
    __register__ = 'commands.setup.PreExecute'

    def run(self, config):
        return self.run_check_modified(config, 'pre_execute')

class PostExecute(Command, Execute):
    __register__ = 'commands.setup.PostExecute'

    def run(self, config):
        return self.run_check_modified(config, 'post_execute')
